package xyz.playedu.resource.service.impl;

import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.html.HTMLCollection;
import org.w3c.dom.html.HTMLDocument;
import org.w3c.dom.html.HTMLElement;
import xyz.playedu.common.context.BCtx;
import xyz.playedu.common.types.paginate.PaginationResult;
import xyz.playedu.common.types.paginate.ResourcePaginateFilter;
import xyz.playedu.common.types.paginate.ResourceTextPaginateFilter;
import xyz.playedu.resource.domain.Resource;
import xyz.playedu.resource.domain.ResourceText;
import xyz.playedu.resource.domain.ResourceTextNode;
import xyz.playedu.resource.domain.ResourceTextResponse;
import xyz.playedu.resource.mapper.ResourceTextMapper;
import xyz.playedu.resource.service.ResourceService;
import xyz.playedu.resource.service.ResourceTextService;
import xyz.playedu.resource.utils.ResourceTextHelper;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ResourceTextImpService extends ServiceImpl<ResourceTextMapper , ResourceText> implements ResourceTextService {

    @Autowired
    ResourceService resourceService;

    @Override
    public ResourceTextResponse saveResourceTexts(int catalogId, int rid,String name,int duration, List<ResourceText> resourceTextList) {
       Resource resource = resourceService.getById(rid);
       ResourceTextResponse resourceTextResponse=new ResourceTextResponse();
       Map<Integer,Integer> idsMap=new HashMap<>();
       if(resource ==null){
           resource = resourceService.create(BCtx.getId(),catalogId+"","RichText",name,"", (long) duration,"","","","");
       }else{
           resource.setName(name);
           resource.setSize(Long.valueOf(duration));
           resourceService.saveOrUpdate(resource);
       }
       int  newRid = resource.getId();
        resourceTextList.forEach(resourceText -> {
            int id1= resourceText.getId();
            resourceText.setRid(newRid);
            resourceText.setCreatedAt(new Date());
            ResourceText resourceText1=  this.getById(resourceText.getId());
            if(resourceText1==null){
                resourceText.setId(null);
                this.save(resourceText);
            }else{
                this.updateById(resourceText);
            }
            log.info(resourceText.toString());
            idsMap.put(id1,resourceText.getId());
        });
        resourceTextResponse.setIdMaps(idsMap);
        resourceTextResponse.setRid(newRid);
        this.checkDeleteResource(resourceTextList,newRid);

        return resourceTextResponse;
    }

    private  void checkDeleteResource(List<ResourceText> list,int rid){
        QueryWrapper<ResourceText> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("rid",rid);
        List<ResourceText> existsResourceTexts = this.list(queryWrapper);
        for(ResourceText resourceText:existsResourceTexts){
            int id=resourceText.getId();
            List<ResourceText> resourceTexts = list.stream().filter(resourceText1 -> {
                return resourceText1.getId() ==id;
            }).toList();
            if(resourceTexts.isEmpty()){
                log.info(id+"已经删除");
                this.removeById(id);
            }
        }
    }

    @Override
    public void removeByRid(int rid) {
        remove(query().getWrapper().eq("rid", rid));
    }

    @Override
    public List<ResourceText> getResourceTextByRid(int rid) {
        QueryWrapper<ResourceText> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("rid",rid);

        List<ResourceText> resourceTexts = this.list(queryWrapper);
        resourceTexts.forEach(resourceText -> {
            String html = resourceText.getContent();
             ResourceTextNode resourceTextNode = this.parseHtml(html);
             resourceText.setResourceNodes(resourceTextNode);
        });
        return resourceTexts;
    }

    @Autowired
    ResourceTextHelper resourceTextHelper;

    @Override
    public ResourceTextNode  parseHtml(String htmlContent) {
        ResourceTextNode resourceTextNode=new ResourceTextNode();
        List<ResourceTextNode> resourceTextNodes = new ArrayList<>();
        CleanerProperties cleanerProperties=new CleanerProperties();
        HtmlCleaner htmlCleaner=new HtmlCleaner(cleanerProperties);
        TagNode tagNode= htmlCleaner.clean(htmlContent);
         this.getHtmlResourceTextNode(tagNode,resourceTextNodes);
        resourceTextHelper.processResourceTextChildNode(resourceTextNodes);
        resourceTextNode.setHtmlContent(htmlCleaner.getInnerHtml(tagNode));
        resourceTextNode.setChildren(resourceTextNodes);
        resourceTextNode.setElementId("root");
        resourceTextNode.setNodeName("root");
        return resourceTextNode;
    }


    private void getHtmlResourceTextNode(TagNode tagNode, List<ResourceTextNode> resourceTextNodes ){
        String name = tagNode.getName();
        if(name.startsWith("h") && name.length()==2){
            ResourceTextNode hresourceNode=new ResourceTextNode();
            hresourceNode.setNodeName(tagNode.getText().toString());
            hresourceNode.setElmentType(name);
            String uuid = UUID.randomUUID().toString();
            hresourceNode.setElementId(uuid);
            Map<String,String> attribute=new HashMap<>();
            attribute.put("id",uuid);
            tagNode.setAttributes(attribute);
            hresourceNode.setHtmlContent(tagNode.getText().toString());
            resourceTextNodes.add(hresourceNode);
        }
        tagNode.getChildTagList().forEach(tagNode1 -> {
            this.getHtmlResourceTextNode(tagNode1,resourceTextNodes);
        });
    }
    /**
     * 获得文章标题
     * @param resourceTexts
     * @return
     */
    private String getTitle(List<ResourceText> resourceTexts){
        StringBuffer titleBuffer=new StringBuffer();
        resourceTexts.forEach(resourceText -> {
            if(titleBuffer.length()>0){
                titleBuffer.append(","+(resourceText.getTitle()));
            }else{
                titleBuffer.append((resourceText.getTitle()));
            }

        });
        if(titleBuffer.length()>200){
            return titleBuffer.subSequence(1,200).toString();
        }
        return titleBuffer.toString();
    }
}
